<template>
    <el-main>
        <!-- 查询条件 -->
    <el-form ref="searchForm" label-width="80px" :inline="true" size="small">
      <el-form-item>
        <el-input v-model="searchModel.roleName" placeholder="请输入角色名称"/>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="el-icon-search" @click="search(pageNo,pageSize)">查询</el-button>
        <el-button icon="el-icon-refresh-right" @click="resetValue">重置</el-button>
        <el-button type="success" icon="el-icon-plus" @click="openAddWindow()" v-if="hasPermission('sys:role:add')">新增</el-button>
      </el-form-item>
    </el-form>
    <!-- 表格 -->
    <el-table :data="roleList" :height="tableHeight" border stripe style="width: 100%; margin-bottom: 10px">
        <el-table-column prop="id" label="角色编号" width="100" align="center"></el-table-column>
        <el-table-column prop="roleCode" label="角色编码" align="center"></el-table-column>
        <el-table-column prop="roleName" label="角色名称" align="center"></el-table-column>
        <el-table-column prop="remark" label="备注" align="center"></el-table-column>
        <el-table-column  label="操作" align="center" width="290">
            <template slot-scope="scope">
                <el-button icon="el-icon-edit" type="text" size="small" @click="handleEdit(scope.row)" v-if="hasPermission('sys:role:edit')">编辑</el-button>
                <el-button icon="el-icon-delete" type="text" size="small" @click="handleDelete(scope.row)" v-if="hasPermission('sys:role:delete')">删除</el-button>
                <el-button icon="el-icon-setting" type="text" size="small" @click="assignRole(scope.row)" v-if="hasPermission('sys:role:assign')">分配权限</el-button>
            </template>
        </el-table-column>
    </el-table>
    <!-- 分页工具栏 -->
        <el-pagination background
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
        :current-page="pageNo"
        :page-sizes="[10, 20, 30, 40, 50]"
        :page-size="10"
        layout="total, sizes, prev, pager, next, jumper"
        :total="total" align="center">
        </el-pagination>

    <!-- 添加修改窗口 -->
    <system-dialog
        :title="roleDialog.title"
        :visible="roleDialog.visible"
        :width="roleDialog.width"
        :height="roleDialog.height"
        @onClose="onClose"
        @onConfirm="onConfirm">
        <div slot="content">
            <el-form :model="role" ref="roleForm" :rules="rules" :inline="false" label-width="80px" size="small">
                <el-form-item label="角色编码" prop="roleCode">
                    <el-input v-model="role.roleCode"></el-input>
                </el-form-item>
                <el-form-item label="角色名称" prop="roleName">
                    <el-input v-model="role.roleName"></el-input>
                </el-form-item>
                <el-form-item label="备注" prop="remark">
                    <el-input
                        type="textarea"
                        :rows="5"
                        placeholder="备注"
                        v-model="role.remark">
                    </el-input>
                </el-form-item>
            </el-form>
        </div>
    </system-dialog>

    <!-- 分配权限树窗口 -->
        <system-dialog
        :title="assignDialog.title"
        :visible="assignDialog.visible"
        :width="assignDialog.width"
        :height="assignDialog.height"
        @onClose="onAssignClose"
        @onConfirm="onAssignConfirm">
        <div slot="content">
            <el-tree ref="assignTree"
                :data="assignTreeData" node-key="id"
                :props="defaultProps" empty-text="暂无数据"
                :show-checkbox="true"
                :highlight-current="true" default-expand-all></el-tree>
        </div>
        </system-dialog>
    </el-main>
</template>
<script>
import {getRoles,addRole,updateRole,deleteRole,checkRole,getAssignTreeApi,assignSaveApi} from '@/api/role';
//导入对话框组件
import SystemDialog from '@/components/system/SystemDialog.vue';
//导入末级节点脚本
import leafUtils from '@/utils/leaf'
export default {
    name: 'roleList',
    components:{
        SystemDialog
    },
    data(){
        return {
            searchModel:{
                roleName: '',
                pageNo:1,
                pageSize:10,
                userId:this.$store.getters.userId //用户ID
            },
            roleList:[],
            tableHeight: 0, //表格高度
            pageNo: 1, //当前页码
            pageSize: 10, //每页显示数量
            total: 0, //总数量

            roleDialog:{
                title:"",
                visible:false,
                width:500,
                height:230,
            },
            role:{//角色对象
                id:"",
                roleCode:"",
                roleName:"",
                remark:"",
                createUser:"",
            },
            rules:{
                roleCode: [{ required: true, trigger: "blur", message: "请输入角色编码"}],
                roleName: [{ required: true, trigger: "blur", message: "请输入角色名称" }],
            },
            //分配权限窗口属性
            assignDialog: {
            title: '',
            visible: false,
            height: 450,
            width: 300
            },
            roleId: '', //角色ID
            assignTreeData: [], //树节点数据
            //树节点属性
            defaultProps: {
            children: 'children',
            label: 'label'
            }
        }
    },
    methods:{
        /**
        * 查询
        */
        async search(pageNo=1,pageSize=10) { 
            this.searchModel.pageNo = pageNo;//当前页码
            this.searchModel.pageSize = pageSize;//每页显示数量
            //发送查询请求
            let res = await getRoles(this.searchModel);
            //执行成功
            if (res.success) {
            //角色列表
            this.roleList = res.data.records;
            //总数量
            this.total = res.data.total;
            }
        },
        /**
        * 重置查询条件
        */
        resetValue() {
        //清空查询条件
        this.searchModel.roleName="";
        //重新查询
        this.search();
        },
        /**
        * 当每页数量发生变化时触发该事件
        */
        handleSizeChange(size) {
            this.pageSize = size; //将每页显示的数量交给成员变量
            this.search(this.pageNo, size);
        },
        /**
        * 当页码发生变化时触发该事件
        */
        handleCurrentChange(page) {
            this.pageNo = page;
            //调用查询方法
            this.search(page, this.pageSize);
        },
        /**
        * 打开编辑窗口
        */
        handleEdit(row) {
            this.$objCopy(row, this.role);
            this.roleDialog.title = "编辑角色";
            this.roleDialog.visible = true;
        },
        /**
        * 删除
        */
        async handleDelete(row) {
            //验证角色是否被分配给用户
            let result = await checkRole({id:row.id})
            if(!result.success){
                this.$message.warning(result.message)
            }else{
                let confirm =await this.$myconfirm("确定要删除该数据吗?");
                if(confirm){
                    //删除请求
                let res = await deleteRole({id:row.id})
                if(res.success){
                    this.$message.success(res.message);
                    this.search(this.pageNo,this.pageSize);
                }else{
                    this.$message.error(res.message);
                }
                }
                
            }

        },
        /**
         * 打开新增窗口
         */
        openAddWindow(){
            //清空表单数据
            this.$resetForm("roleForm", this.role);
                //设置窗口标题
            this.roleDialog.title = "新增角色";
                //显示添加部门窗口
            this.roleDialog.visible = true;
        },
        //关闭窗口
        onClose(){
            this.roleDialog.visible = false;
        },
        //确认窗口
        onConfirm(){
            this.$refs.roleForm.validate(async (valid)=>{
                let res = null;
                if(valid){
                    if(this.role.id===''){
                        //增加请求
                        this.role.createUser=this.$store.getters.userId;
                        res = await addRole(this.role);
                    }else{
                        //修改请求
                        res = await updateRole(this.role);
                    }
                    if(res.success){
                        this.$message.success(res.message);
                        this.search(this.pageNo,this.pageSize)
                        this.roleDialog.visible = false;
                    }else{
                        this.$message.error(res.message);
                    }
                }
            });
            
        },
        //分配角色窗口
        /**
        * 分配权限
        */
        async assignRole(row){
            //设置角色ID
            this.roleId = row.id
            //构建后端接口所需参数
            let params = {
            roleId: row.id,
            userId: this.$store.getters.userId
            }
            //发送查询请求
            let res = await getAssignTreeApi(params)
            if (res.success) {
            //获取当前登录用户拥有的所有权限
            let permissionList = res.data.permissionList
            //获取当前被分配的角色已经拥有的权限信息
            let checkList = res.data.checkList
            //判断当前菜单是否是末级
            let { setLeaf } = leafUtils()
            //设置权限菜单列表
            let newPermissionList = setLeaf(permissionList)
            //设置树节点菜单数据
            this.assignTreeData = newPermissionList
            //将回调延迟到下次DOM更新循环之后执行,在修改数据之后立即使用它,然后等待DOM更新。
            this.$nextTick(() => {
                //获取树菜单的节点数据
                let nodes = this.$refs.assignTree.children
                //设置子节点
                this.setChild(nodes, checkList)
                })
            }
            this.assignDialog.visible = true;
            //设置窗口标题
            this.assignDialog.title = `给【${row.roleName}】分配权限`
        },
        /**
        * 设置子节点
        */
        setChild(childNodes, checkList) {
            //判断是否存在子节点
            if (childNodes && childNodes.length > 0) {
                //循环所有权限
                for (let i = 0; i < childNodes.length; i++) {
                    //根据 data 或者 key 拿到 Tree 组件中的 node
                    let node = this.$refs.assignTree.getNode(childNodes[i])
                    //判断是否已经拥有对应的角色数据
                    if (checkList && checkList.length > 0) {
                        //循环遍历已有的权限集合
                        for (let j = 0; j < checkList.length; j++) {
                            //找到已经存在的菜单权限节点
                            if (checkList[j] == childNodes[i].id) {
                                //如果节点是展开状态，则将树节点选中
                                if (childNodes[i].open) {
                                    this.$refs.assignTree.setChecked(node, true)
                                    break
                                }
                            }
                        }
                    }
                    //如果存在子节点，则递归选中
                    if (childNodes[i].children) {
                        this.setChild(childNodes[i].children, checkList)
                    }
                }
            }
        },
        //关闭窗口
        onAssignClose(){
            this.assignDialog.visible = false;
        },
        //确认窗口
        async onAssignConfirm(){
            //获取选中的节点key
            let ids = this.$refs.assignTree.getCheckedKeys()
            //获取选中节点的父节点id
            let pids = this.$refs.assignTree.getHalfCheckedKeys()

            let List = ids.concat(pids)
            
            let params = {
                roleId:this.roleId,
                list:List
            }

            let res = await assignSaveApi(params)
            if(res){
                this.$message.success(res.message)
            }else{
                this.$message.error(res.message)
            }
            this.assignDialog.visible = false;
        }


    },
    //初始化时调用
    created() {
        this.search()
    },
    //挂载后调用
    mounted() {
    this.$nextTick(() => {
    this.tableHeight = window.innerHeight - 220
        })
    }
};
</script>
<style lang="scss" scoped></style>